;;;;;;;;;;;;;;;;;;;;  functions for c  ;;;;;;;;;;;;;;;;;;;;

(setq tags-table-list '("/scratch/programming/ctest/GTAGS" "/scratch/programming/c/GTAGS" "/usr/include/GTAGS" "/usr/local/include/GTAGS"))
(defun create-tags (dir-name)
  "Create tags file."
  (interactive "DDirectory: ")
  (eshell-command 
   (format "find %s -type f -name \"*.[ch]\" | etags -" dir-name)))

(define-skeleton skeleton-c-mode-main-func
  "generate int main(int argc, char * argv[]) automatic" nil
  "int main (int argc, char * argv[]) \n{\n"
  > _  "\n" > "return 0;"
  "\n}")
(define-skeleton skeleton-c-mode-mainv-func
  "generate int main(void) automatic" nil
  "int main (void) \n{\n"
  > _  "\n" > "return 0;"
  "\n}")
(define-skeleton skeleton-c-mode-unpipc-func
  "generate #include \"unpipc.h\"" nil
  "#include \"unpipc.h\"\n"
  > _)
(define-skeleton skeleton-c-mode-apue-func
  "generate #include \"apue.h\"" nil
  "#include \"apue.h\"\n"
  > _)

(define-abbrev-table 'c-mode-abbrev-table '(
                                            ("main" "" skeleton-c-mode-main-func 1)
                                            ("mainv" "" skeleton-c-mode-mainv-func 1)
                                            ("unpipc" "" skeleton-c-mode-unpipc-func 1)
                                            ("apue" "" skeleton-c-mode-apue-func 1)
                                            ))
(define-abbrev-table 'c++-mode-abbrev-table '(
                                              ("main" "" skeleton-c-mode-main-func 1)
                                              ("mainv" "" skeleton-c-mode-mainv-func 1)
                                              ("unpipc" "" skeleton-c-mode-unpipc-func 1)
                                              ("apue" "" skeleton-c-mode-apue-func 1)
                                              ))

(defun new-line-and-insert-item ()
  (interactive)
  (let (curr next)
    (beginning-of-line)
    (cond ((looking-at "\\(\\s-*\\)\\([0-9|\*|\/\*]+\\)\\s-*")
           (setq curr (string-to-number (buffer-substring (match-beginning 2)
                                                          (match-end 2))))
           (end-of-line)
           (insert "\n" (buffer-substring (match-beginning 1)
                                          (match-end 1))
                   "* "))
          (t
           (progn
             (end-of-line)
             (newline-and-indent))))))

(defun insert-semicolon()
  (interactive)
  (end-of-line)
  (insert ";")
  (if c-auto-newline (newline-and-indent))
  )

(defun end-of-newline()
  (interactive)
  (end-of-line)
  (newline-and-indent)
  )


;;;;;;;;;;;;;;;;;;;;  misc  ;;;;;;;;;;;;;;;;;;;;
;;; all from internet, with original names
(defun go-to-char (n char)
  "Move forward to Nth occurence of CHAR.
Typing `go-to-char-key' again will move forwad to the next Nth
occurence of CHAR."
  (interactive "p\ncGo to char: ")
  (search-forward (string char) nil nil n)
  (while (char-equal (read-char)
                     char)
    (search-forward (string char) nil nil n))
  (setq unread-command-events (list last-input-event)))

(defun my-move-line-up (p)
  "move current line up"
  (interactive "p")
  (let ((c (current-column)))
    (beginning-of-line)
    (kill-line 1)
    (forward-line (- 0 p))
    (beginning-of-line)
    (yank)
    (forward-line -1)
    (move-to-column c)))

(defun my-move-line-down (p) 
  "move current line down"
  (interactive "p")
  (let ((c (current-column)))
    (beginning-of-line)
    (kill-line 1)
    (forward-line p)
    (beginning-of-line)
    (yank)
    (forward-line -1)
    (move-to-column c)))

(defun my-dup-line-down ()
  "duplicate this line at next line"
  (interactive)
  (let ((c (current-column)))
    (beginning-of-line)
    (ue-select-line-down)
    (beginning-of-line)
    (yank)
    (forward-line -1)
    (move-to-column c)))

(defvar ue-selection-last-point nil
  "Indicates whether to kill-append or kill-new")
(defvar ue-selection-total-lines 0
  "Total number of lines appended so far to the last item in kill-ring")
(defun ue-selection-update-cont ()
  "Update `ue-selection-last-point' variable"
  (if (and this-command
           (string= (format "%s" this-command)
                    "ue-select-line-down-continued"))
      (setq ue-selection-last-point (point))
    (setq ue-selection-total-lines 0)
    (setq ue-selection-last-point  nil)))

(defun ue-select-line-down-continued ()
  "like Shift+down in UltraEdit, but do no selection.
Just put these continuous lines all toghether as a new item in kill-ring.
Messages will appear in minibuffer telling you how many lines were copied.
Continuous commands with no interruption append new lines to the item.
Any non-ue-select-line-down-continued command will stop gathering new lines
and make a new item in kill-ring.
post-command-hook is used in detecting the continuity of this command.
check `ue-selection-update-cont' and `post-command-hook'."
  (interactive)
  (let ((s (point)))
    (setq next-line-add-newlines t)
    (forward-line 1)
    (setq next-line-add-newlines nil)
    (if (and ue-selection-last-point
             (= (save-excursion
                  (when (> (count-lines (point-min) (point)) 1)
                    (forward-line -1))
                  (point))
                ue-selection-last-point))
        (progn
          (kill-append (buffer-substring s (point)) nil)
          (setq ue-selection-total-lines (1+ ue-selection-total-lines))
          (message (format "%s lines copied" ue-selection-total-lines)))
      (kill-new (buffer-substring s (point)))
      (message "1 line copied")
      ;; some errors will cause post-command-hook deletion
      ;; so add-hook every time after we add the first line
      (add-hook 'post-command-hook 'ue-selection-update-cont)
      (setq ue-selection-total-lines 1))))

(defun ue-select-line-down ()
  "like Shift+down in UltraEdit."
  (interactive)
  (let ((s (point)))
    (setq next-line-add-newlines t)
    (forward-line 1)
    (setq next-line-add-newlines nil)
    (kill-new (buffer-substring s (point)))))


(defun copy-word (&optional arg)
  "Copy words at point"
  (interactive "P")
  (let ((beg (progn (if (looking-back "[a-zA-Z]" 1) (backward-word 1)) (point))) 
        (end (progn (forward-word arg) (point))))
    (copy-region-as-kill beg end))
  )

(defun copy-line (&optional arg)
  "Save current line into Kill-Ring without mark the line "
  (interactive "P")
  (let ((beg (line-beginning-position)) 
        (end (line-end-position)))  
    (copy-region-as-kill beg end))
  )
(defun copy-paragraph (&optional arg)
  "Copy paragraphes at point"
  (interactive "P")
  (let ((beg (progn (backward-paragraph 1) (point))) 
        (end (progn (forward-paragraph arg) (point))))
    (copy-region-as-kill beg end))
  )


(defvar cancel-auto-new-line-command-list
  '(next-line previous-line)
  "a list of command which will trigger the cancel.")

(defun cancel-auto-new-line ()
  (interactive)
  (save-excursion
    (if (and (eq last-command 'c-electric-semi&comma)
             (memq this-command cancel-auto-new-line-command-list))
        (progn
          (if (and (boundp c-auto-newline) c-auto-newline)
              (progn
                (delete-blank-lines)
                (delete-blank-lines)))))))


(defun hvj-recursive-count-words (region-end)
  "Number of words between point and REGION-END."
  (if (and (< (point) region-end)
           (re-search-forward "\\w+\\W*" region-end t))
      (1+ (hvj-recursive-count-words region-end))
    0))

(defun hvj-count-words-region (beginning end)
  "Print number of words in the region.
Words are defined as at least one word-constituent
character followed by at least one character that is
not a word-constituent. The buffer's syntax table
determines which characters these are."
  (interactive "r")
  (message "Counting words in region ... ")
  (save-excursion
    (goto-char beginning)
    (let ((count (hvj-recursive-count-words end)))
      (cond ((zerop count)
             (message
              "The region does NOT have any words."))
            ((= 1 count)
             (message "The region has 1 word."))
            (t
             (message
              "The region has %d words." count))))))


(defun hvj-line-to-top-of-window ()
  "Move the line point is on to top of window."
  (interactive)
  (recenter 0))

;;;;;;;;;;;;;;;;view ascii table;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun ascii-table-show ()
  "Print the ascii table"
  (interactive)
  (with-current-buffer (switch-to-buffer "*ASCII table*")
    (erase-buffer)
    (let ((i   0)
          (tmp 0))
      (insert (propertize
               "                                [ASCII table]\n\n"
               'face font-lock-comment-face))
      (while (< i 32)
        (dolist (tmp (list i (+ 32 i) (+ 64 i) (+ 96 i)))
          (insert (concat
                   (propertize (format "%3d " tmp)
                               'face font-lock-function-name-face)
                   (propertize (format "[%2x]" tmp)
                               'face font-lock-constant-face)
                   "      "
                   (propertize (format "%3s" (single-key-description tmp))
                               'face font-lock-string-face)
                   (unless (= tmp (+ 96 i))
                     (propertize " | " 'face font-lock-variable-name-face)))))
        (newline)
        (setq i (+ i 1)))
      (goto-char (point-min)))
    (local-set-key "q" 'kill-this-buffer)
    (toggle-read-only 1)
    (message "Press q to quit.")))

;;;;;;;;;;;;;;;;;;;;  for tax table   ;;;;;;;;;;;;;;;;;;;;
(defvar tax-table 
  '((0 500 0.05)
    (500 2000 0.1)
    (2000 5000 0.15)
    (5000 20000 0.20)
    (20000 40000 0.25)
    (40000 60000 0.30)
    (60000 80000 0.35)
    (80000 100000 0.40)
    (100000 1e12 0.45))
  "Tax Table")
(defun tax-calculation-internal(tax-income tax-table)
  (if (not tax-table)
      0
    (let ((i (car tax-table)))
      (cond 
       ((< tax-income (car i)) 0)
       ((< tax-income (cadr i)) (* (- tax-income (car i)) (caddr i)))
       (t (+ (tax-calculation-internal tax-income (cdr tax-table))
             (* (- (cadr i) (car i)) (caddr i))))))))

(defun tax-calculation(income )
  (interactive "nPlease Input Your Salary:")
  (message (apply 'concat (mapcar (lambda (x)
                                    (let ((tax-initial x))
                                      (format "Start Point is %4.2f, Tax is %4.2f\n" 
                                              tax-initial
                                              (tax-calculation-internal
                                               (max 0 (- income tax-initial))
                                               tax-table))))
                                  '(1100 1500 1600)))))


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;for dir;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun his-dired-sort ()
  "Dired sort hook to list directories first."
  (save-excursion
    (let (buffer-read-only)
      (forward-line 2) ;; beyond dir. header
      (sort-regexp-fields t "^.*$" "[ ]*." (point)
                          (point-max))))
  (and (featurep 'xemacs)
       (fboundp 'dired-insert-set-properties)
       (dired-insert-set-properties (point-min) (point-max)))
  (set-buffer-modified-p nil))




(defun ywb-dired-filter-regexp (regexp &optional arg)
  (interactive
   (list (dired-read-regexp
          (concat (if current-prefix-arg "Exclude" "Exclude not")
                  " match (regexp): "))
         current-prefix-arg))
  (dired-mark-files-regexp regexp)
  (or arg (dired-toggle-marks))
  (dired-do-kill-lines))

(defun ywb-dired-filter-extension (extension &optional arg)
  (interactive
   (list (read-from-minibuffer
          (concat "Exclude extension is "
                  (if current-prefix-arg "" "not") ": "))
         current-prefix-arg))
  (ywb-dired-filter-regexp (concat "\\." extension "\\'") arg))

(defun ywb-insert-item ()
  (interactive)
  (let (curr next)
    (beginning-of-line)
    (cond ((looking-at "\\(\\s-*\\)\\([0-9]+\\)\\.\\s-*")
           (setq curr (string-to-number (buffer-substring (match-beginning 2)
                                                          (match-end 2))))
           (setq next (number-to-string (1+ curr)))
           (end-of-line)
           (insert "\n" (buffer-substring (match-beginning 1)
                                          (match-end 1))
                   next ". ")
           (ywb-sync-item))
          ((looking-at "\\s-*[-+]\\s-*")
           (progn
             (end-of-line)
             (insert "\n" (buffer-substring (match-beginning 0)
                                            (match-end 0)))))
          (t
           (progn
             (end-of-line)
             (newline-and-indent))))))

(defun ywb-sync-item ()
  (interactive)
  (save-excursion
    (beginning-of-line)
    (if (looking-at "\\(\\s-*\\)\\([0-9]+\\)\\.\\s-*")
        (let ((curr (string-to-number (buffer-substring (match-beginning 2)
                                                        (match-end 2))))
              (blank1 (buffer-substring (match-beginning 1)
                                        (match-end 1)))
              (blank2 (buffer-substring (match-end 2)
                                        (match-end 0))))
          (while (progn
                   (beginning-of-line 2)
                   (looking-at "\\s-*[0-9]+\\.\\s-*"))
            (setq curr (1+ curr))
            (delete-region (match-beginning 0) (match-end 0))
            (insert blank1 (number-to-string curr) blank2))))))


;;;;;;;;;;;;;;;;;;;;;;;;;;others;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun his-match-paren (arg)
  "Go to the matching paren if on a paren; otherwise insert %."
  (interactive "p")
  (let ((prev-char (char-to-string (preceding-char)))
        (next-char (char-to-string (following-char))))
    (cond ((string-match "[[{(<]" next-char) (forward-sexp 1))
          ((string-match "[\]})>]" prev-char) (backward-sexp 1))
          (t (self-insert-command (or arg 1))))))


(defun ywb-indent-accoding-to-paren ()
  "Indent the region between paren"
  (interactive)
  (let ((prev-char (char-to-string (preceding-char)))
        (next-char (char-to-string (following-char)))
        (pos (point)))
    (save-excursion
      (cond ((string-match "[[{(<]" next-char)
             (indent-region pos (progn (forward-sexp 1) (point)) nil))
            ((string-match "[\]})>]" prev-char)
             (indent-region (progn (backward-sexp 1) (point)) pos nil))))))



;;;###autoload
(defun ywb-html-preview-region (beg end)
  (interactive "r")
  (let ((file (make-temp-file "region-" nil ".html")))
    (write-region beg end file)
    (browse-url file)))
(defvar rotate-text-definations
  '(("[0-9]+" . (lambda (arg)
                  (format "%d" (+ arg (string-to-number (match-string 0))))))
    ("zero" "one" "two" "three" "four" "five" "six" "seven" "eight" "nine"))
  "
a list of ROT text defination. each element is a defination.
element can be a list of string.
element can be a cons. (REGEXP . func)
if REGEXP matched, func is called with no args, return value is the next value.
")

(defun rotate-text-aux (arg)
  (catch 'break
    (mapc
     #'(lambda (def)
         (let ((regexp (if (functionp (cdr def))
                           (car def)
                         (mapconcat 'regexp-quote def "\\|")))
               (func (if (functionp (cdr def))
                         (cdr def)
                       #'(lambda (arg)
                           (let* ((len (length def))
                                  (rest (member (match-string 0) def))
                                  (pos (- len (length rest))))
                             (format "%s" (nth (mod (+ pos arg) len) def)))))))
           (if (re-search-forward regexp (line-end-position) t nil)
               (throw 'break (funcall func arg)))))
     rotate-text-definations)
    nil))

(defun rotate-text(arg)
  (interactive "p")
  (save-excursion
    (let ((x (rotate-text-aux arg)))
      (if x (replace-match x)))))


;;###autoload
(defun ywb-favorite-window-config (&optional percent)
  "Split window to proper portion"
  (interactive "P")
  (or percent (setq percent 50))
  (setq percent (/ percent 100.0))
  (let (buf)
    (if (> (length (window-list)) 1)
        (setq buf (window-buffer (next-window))))
    (delete-other-windows)
    (let ((maxwidth (window-width)))
      (split-window-horizontally (round (* maxwidth percent))))
    (if buf (save-selected-window
              (pop-to-buffer buf))))
  (call-interactively 'his-transpose-windows))

;; transpose(interchange) two windows
;;;###autoload
(defun his-transpose-windows (arg)
  "Transpose the buffers shown in two windows."
  (interactive "p")
  (let ((selector (if (>= arg 0) 'next-window 'previous-window)))
    (while (/= arg 0)
      (let ((this-win (window-buffer))
            (next-win (window-buffer (funcall selector))))
        (set-window-buffer (selected-window) next-win)
        (set-window-buffer (funcall selector) this-win)
        (select-window (funcall selector)))
      (setq arg (if (plusp arg) (1- arg) (1+ arg))))))

(defun his-imenu()
  "Call imenu, showing completions."
  (interactive)
  (setq unread-command-events (list 9))
  ;; (imenu (imenu-choose-buffer-index))
  )

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; for ehshell

(defun eshell-scroll-to-bottom (window display-start)
  (if (and window (window-live-p window))
      (let ((resize-mini-windows nil))
	(save-selected-window
	  (select-window window)
	  (save-restriction
	    (widen)
	    (when (> (point) eshell-last-output-start) ; we're editing a line. Scroll.
	      (save-excursion
		(recenter -1)
		(sit-for 0))))))))

 (defun eshell-bol-maybe-my ()
   ""
   (interactive)
   (bol-maybe-general-my (funcall eshell-prompt-function)))
(defun eshell-add-scroll-to-bottom ()
  (interactive)
  ;; (make-local-hook 'window-scroll-functions)
  (add-hook 'window-scroll-functions 'eshell-scroll-to-bottom nil t))



(defun eshell-handle-ansi-color ()
  (ansi-color-apply-on-region eshell-last-output-start
                              eshell-last-output-end))
;;(add-to-list 'eshell-output-filter-functions 'eshell-handle-ansi-color)


 ;;;###autoload
(defun bol-maybe-general-my (prompt &optional alt-bol-fcn)
  ""
  (interactive)
  (if (and (string-match (concat "^" (regexp-quote prompt)
                                 " *$")
                         (buffer-substring-no-properties
                          (line-beginning-position)
                          (point)))
           (not (bolp)))
      (beginning-of-line)
    (if alt-bol-fcn
        (funcall alt-bol-fcn)
      (beginning-of-line)
      (search-forward-regexp prompt))))

;;;;;;;;;;;;;;;;for dictionary;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun my-retate-windows ()
  (interactive)
  (if (= (count-windows) 2)
      (let* ((wl    (window-list))
             (w1    (frame-first-window))
             (w2    (if (equal w1 (car wl)) (cadr wl) (car wl)))
             (b1    (window-buffer w1))
             (b2    (window-buffer w2))
             (first (if (equal (current-buffer) b1) t nil)))
        (if (= (window-width) (frame-width))
            (split-window-horizontally)
          (split-window-vertically))
        (other-window 2)
        (delete-window)
        (switch-to-buffer b1)
        (other-window 1)
        (switch-to-buffer b2)
        (when first (other-window 1)))
    (message "There are not exactly 2 windows.")))

;;;;;;;;;;;;;;;;;;;for register;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar regadhoc-register-char-list
  (list ?a ?b ?c ?d ?e ?f ?g)
  "list of register name(char).")

(defun regadhoc-delete-register (name alist)
  "Delq register in alist.
alist is like register-alist. See register.el"
  (let ((elt (assoc (string-to-char name) alist)))
    (if elt	(delq elt alist))))

(defun regadhoc-clear-register ()
  "Clear all register."
  (interactive)
  ;; TODO
  (setq register-alist nil))

(defun regadhoc-register (&optional arg)
  "Register automatically."
  (interactive "P")
  (let ((r (or (regadhoc-next-register-char regadhoc-register-char-list register-alist)
               (read-char (format 
                           "All register is used. Point to (new) register:\n %s" 
                           (cdr (regadhoc-registers-info register-alist)))))))
    (message "Set Register %s:%s %s" (char-to-string r) (buffer-name) (thing-at-point 'line))
    (point-to-register r arg)))

(defun regadhoc-next-register-char (l r)
  "Return element of l if it's not used in r."
  (cond 
   ((null l) nil)
   ((not (assoc (car l) r))	(car l))
   (t (regadhoc-next-register-char (cdr l) r))))

(defun regadhoc-line-at-marker (marker)
  "Return line at marker."
  (if marker
      (save-current-buffer
        (set-buffer (marker-buffer marker))
        (goto-char (marker-position marker))
        (thing-at-point 'line))))

(defun regadhoc-register-marker (contents)
  "Return marker of register."
  (cond
   ((markerp contents) contents)
   ((and (consp contents) (frame-configuration-p (car contents)) (markerp (cadr contents)))
    (cadr contents))
   (t nil)))

(defun regadhoc-registers-info (alist)
  "Return marker register(s) info. (head . msg).
alist is like register-alist. See register.el"
  (let (elt head msg name marker)
    (while alist
      (setq elt (car alist)) ;; (NAME . CONTENTS)
      (setq name (car elt))
      (setq marker (regadhoc-register-marker (cdr elt)))
      (cond 
       ((null marker) nil)
       ((marker-buffer marker)
        (setq head (cons (char-to-string name) head))
        (setq msg (cons (regadhoc-register-format name marker) msg))))
      (setq alist (cdr alist)))
    (cons (mapconcat 'concat head " ") (mapconcat 'concat msg ""))))

(defun regadhoc-show-registers ()
  (interactive)
  (let* ((msg (regadhoc-registers-info register-alist)))
    (message "%s\n%s" (car msg) (cdr msg))))

(defun regadhoc-register-format (name marker)
  "Return register info."
  (format "%s:%s %s"
          (char-to-string name) 
          (if marker (buffer-name (marker-buffer marker)))
          (regadhoc-line-at-marker marker)))

(defun regadhoc-jump-to-registers (register)
  "Jump to registers."
  (interactive
   (let* ((msg (regadhoc-registers-info register-alist))
          (r (read-char-exclusive (concat "Jump to register(SPC is the latest): " (car msg) "\n" (cdr msg)))))
     (list r)))
  (cond
   ((equal (string-to-char " ") register)
    (jump-to-register (caar register-alist))
    (message "Jump to the latest register."))
   (t
    (if (get-register register)
        (jump-to-register register)
      (message "Oops. No such register.")))))

;;;;;;;;;; switch mode;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar switch-major-mode-last-mode nil)
(make-variable-buffer-local 'switch-major-mode-last-mode)

(defun major-mode-heuristic (symbol)
  (and (fboundp symbol)
       (string-match ".*-mode$" (symbol-name symbol))))

(defun switch-major-mode (mode)
  (interactive
   (let ((fn switch-major-mode-last-mode)
         val)
     (setq val
           (completing-read
            (if fn
                (format "Switch major mode to (default %s): " fn)
              "Switch major mode to: ")
            obarray 'major-mode-heuristic t nil nil (symbol-name fn)))
     (list (intern val))))
  (let ((last-mode major-mode))
    (funcall mode)
    (setq switch-major-mode-last-mode last-mode)))
(global-set-key (kbd "C-c m") 'switch-major-mode)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun my-browse-with-emacs-w3m ()
  (interactive)
  (let ((file (dired-get-file-for-visit)))
    (w3m-browse-url file)))


(defun toggle-line-spacing ()
  "Toggle line spacing between 1 and 5 pixels."
  (interactive)
  (if (eq line-spacing 1)
      (setq-default line-spacing 3)
    (setq-default line-spacing 1))
  )

(defun open-eshell-other-buffer ()
  "Open eshell in other buffer"
  (interactive)
  (split-window-vertically)
  (eshell))

(defun delete-cur-word()
  (interactive)
  (progn (forward-word (-  1))
    (mark-word)
    (copy-region-as-kill (region-beginning) (region-end))
    (delete-region (region-beginning) (region-end))))

(defun notify-popup (title msg &optional icon sound)
  "Show a popup if we're on X, or echo it otherwise; TITLE is the title
of the message, MSG is the context. Optionally, you can provide an ICON and
a sound to be played"
  (interactive)
  (when sound (shell-command
                (concat "mplayer -really-quiet " sound " 2> /dev/null")))
  (if (eq window-system 'x)
    (shell-command (concat "notify-send "

                     (if icon (concat "-i " icon) "")
                     " '" title "' '" msg "'"))
    ;; text only version
    (message (concat title ": " msg))))

(defun notify-appt-display (min-to-app new-time msg)
    (notify-popup (format "ORG in %s minute(s)" min-to-app) msg 
      "/usr/share/icons/gnome/32x32/status/appointment-soon.png"
      "/zleinter/emax/sounds/alarm.wav"))

(defun ska-point-to-register()
  "Store cursorposition _fast_ in a register.
Use ska-jump-to-register to jump back to the stored
position."
  (interactive)
  ;; (setq zmacs-region-stays t)
  (point-to-register 8))
(defun ska-jump-to-register()
  "Switches between current cursorposition and position
that was stored with ska-point-to-register."
  (interactive)
  ;; (setq zmacs-region-stays t)
  (let ((tmp (point-marker)))
        (jump-to-register 8)
        (set-register 8 tmp)))


(defun fd-switch-dictionary()
    (interactive)
    (let* ((dic ispell-current-dictionary)
  	 (change (if (string= dic "deutsch8") "english" "deutsch8"))
         (personaldic (if (string= dic "deutsch8") 'emax-personaldic-en 'emax-personaldic-de))
)
      (ispell-change-dictionary change)
      (setq ispell-personal-dictionary personaldic)
      (message "Dictionary switched from %s to %s" dic change)
      ))



;;;;;;;;;;;;;;;;;;;;  junk  ;;;;;;;;;;;;;;;;;;;;
;; (defun kid-star-dict ()
;;   (interactive)
;;   (let ((begin (point-min))
;;         (end (point-max)))
;;     (if mark-active
;;         (setq begin (region-beginning)
;;               end (region-end))
;;       (save-excursion
;;         (backward-word)
;;         (mark-word)
;;         (setq begin (region-beginning)
;;               end (region-end))))
;;     (message "searching for %s ..." (buffer-substring begin end))
;;     (tooltip-show
;;      (shell-command-to-string
;;       (concat "sdcv -n "
;;               (buffer-substring begin end))))))

;; (defun kid-sdcv-to-buffer ()
;;   (interactive)
;;   (let ((word (if mark-active
;;                   (buffer-substring-no-properties (region-beginning) (region-end))
;;                 (current-word nil t))))
;;     (setq word (read-string (format "Search the dictionary for (default %s): " word)
;;                             nil nil word))
;;     (set-buffer (get-buffer-create "*sdcv*"))
;;     (buffer-disable-undo)
;;     (erase-buffer)
;;     (let* ((command (format "sdcv -n %s" word))
;;           (process (start-process-shell-command "sdcv" "*sdcv*" command)))
;;       (set-process-sentinel
;;        process
;;        (lambda (process signal)
;;          (when (memq (process-status process) '(exit signal))
;;            (unless (string= (buffer-name) "*sdcv*")
;; ;;             (setq kid-sdcv-window-configuration (current-window-configuration))
;;              (switch-to-buffer-other-window "*sdcv*")
;;              (local-set-key (kbd "d") 'kid-sdcv-to-buffer)
;;              (local-set-key (kbd "q") (lambda ()
;;                                         (interactive)
;;                                         (bury-buffer)
;;                                         (unless (null (cdr (window-list))) ; only one window
;;                                           (delete-window)))))
;;            (goto-char (point-min))))))))

 ;; (defun pcomplete/eshell-mode/bmk ()
 ;;   "Completion for `bmk'"
 ;;   (pcomplete-here (bookmark-all-names)))

 ;; (defun eshell/bmk (&rest args)
 ;;   "Integration between EShell and bookmarks.
 ;; For usage, execute without arguments."
 ;;   (setq args (eshell-flatten-list args))
 ;;   (let ((bookmark (car args))
 ;;         filename name)
 ;;     (cond
 ;;      ((eq nil args)
 ;;       (format "Usage: bmk BOOKMARK to change directory pointed to by BOOKMARK
 ;;     or bmk . BOOKMARK to bookmark current directory in BOOKMARK.
 ;; Completion is available."))
 ;;      ((string= "." bookmark)
 ;;       ;; Store current path in EShell as a bookmark
 ;;       (if (setq name (car (cdr args)))
 ;;           (progn
 ;;             (bookmark-set name)
 ;;             (bookmark-set-filename name (eshell/pwd))
 ;;             (format "Saved current directory in bookmark %s" name))
 ;;         (error "You must enter a bookmark name")))
 ;;      (t
 ;;       ;; Assume the user wants to go to the path pointed out by a bookmark.
 ;;       (if (setq filename (cdr (car (bookmark-get-bookmark-record bookmark))))
 ;;           (if (file-directory-p filename)
 ;;               (eshell/cd filename)
 ;;             ;; TODO: Handle this better and offer to go to directory
 ;;             ;; where the file is located.
 ;;             (error "Bookmark %s points to %s which is not a directory" 
 ;;                    bookmark filename))
 ;;         (error "%s is not a bookmark" bookmark))))))
 ;;;###autoload

